/**
 * 
 */
package com.estock.common.model.security;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.estock.common.model.security.enums.StockStatus;


/**
 * @author richard
 * 
 */
@Entity
@Table(name="Stock")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
@JsonIgnoreProperties(ignoreUnknown=true)
public class Stock extends Security {

	private static final long serialVersionUID = 5090576339291784116L;
	
	/**
	 *  1: SH
	 *  2: SZ
	 */
	protected int type; 

	/**
	 *  0: inactive
	 *  1: active
	 */
	protected int status;
	
	private int isSelfSelect;
	
	// filter out many to many's circle reference attributes from json response
	// to avoid json convert failure.
	// Also notice that we cannot use FetchType.EAGER fetch strategy because it
	// uses three tables' left join and will get plenty of duplication.
	@ManyToMany(mappedBy="stocks", cascade=CascadeType.ALL)
	@JsonIgnore
	protected List<StockCategory> categories = new ArrayList<StockCategory>();
	
	@OneToOne(mappedBy="stock", cascade=CascadeType.ALL)
	@JsonIgnore
	private StockPrice stockPrice = new StockPrice();
	
	public Stock(String code, String name, int type) {
		super(code, name);
		this.type = type;
	}

	public Stock() {
	}
	
	public int getType() {
		return type;
	}

	public void setType(int type) {
		this.type = type;
	}

	public int getStatus() {
		return status;
	}

	public void setStatus(int status) {
		this.status = status;
	}
	
	public boolean getIsSelfSelect() {
		return (isSelfSelect == 1) ? Boolean.TRUE : Boolean.FALSE;
	}

	public void setIsSelfSelect(boolean isSelfSelect) {
		this.isSelfSelect = isSelfSelect ? 1 : 0;
	}

	@Transient
	public String getStatusName() {
		return StockStatus.getDescByStatus(status);
	}
	
	public List<StockCategory> getCategories() {
		return categories;
	}

	public void setCategories(List<StockCategory> categories) {
		this.categories = categories;
	}
	
	public void setYesterPrice(float yesterPrice) {
		getStockPrice().setYesterPrice(yesterPrice);
	}
	
	public void setLatestPrice(float latestPrice) {
		getStockPrice().setLatestPrice(latestPrice);
	}
	
	public StockPrice getStockPrice() {
		// fix stockprice null primary key issue.
		if (stockPrice.getStock() == null) {
			stockPrice.setStock(this);
		}
		return stockPrice;
	}
	
	@Transient
	public float getYesterPrice() {
		return stockPrice.getYesterPrice();
	}

	@Transient
	public float getLatestPrice() {
		return stockPrice.getLatestPrice();
	}

	/**
	 * Last transaction day recorded in dailytrans table.<br>
	 * Attent that last trans day's price not must equals latestprice.
	 * 
	 * @return
	 */
	@Transient
	public Date getLastTransDay() {
		return stockPrice.getLastTransDay();
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null || !(obj instanceof Stock)) return false;
		return this.getCode().equals(((Stock)obj).getCode());
	}

}
